import service from './service'
import { CONTENT_TYPE } from '@/constants'
import { useUserStoreWithOut } from '@/store/modules/user'

const request = (option: AxiosConfig) => {
  const { url, method, params, data, headers, responseType } = option
  const userStore = useUserStoreWithOut()
  return service.request({
    url: url,
    method,
    params,
    data,
    responseType: responseType,
    headers: {
      'Content-Type': CONTENT_TYPE,
      [userStore.getTokenKey ?? 'Authorization']: userStore.getToken ?? '',
      ...headers
    }
  })
}

const downloadFileRequest = (option: AxiosConfig) => {
  const { url, method, params, data, headers } = option
  const userStore = useUserStoreWithOut()
  return service
    .request({
      url: url,
      method,
      params,
      data,
      responseType: 'blob',
      headers: {
        'Content-Type': 'application/octet-stream',
        [userStore.getTokenKey ?? 'Authorization']: userStore.getToken ?? '',
        ...headers
      }
    })
    .then((response: any) => {
      // 创建一个 Blob 对象
      const blob = new Blob([response.data], { type: response.headers['content-type'] })
      // 创建一个 URL 对象
      const url = window.URL.createObjectURL(blob)
      // 创建一个 <a> 标签
      const link = document.createElement('a')
      link.href = url
      // 从响应头中获取文件名
      const contentDisposition = response.headers['content-disposition']
      const filenameRegex = /filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/
      const matches = filenameRegex.exec(contentDisposition)
      if (matches != null && matches[1]) {
        let filename = matches[1].replace(/['"]/g, '')
        filename = decodeURIComponent(filename)
        link.download = filename
      }
      // 模拟点击该标签
      document.body.appendChild(link)
      link.click()
      // 释放 URL 对象
      window.URL.revokeObjectURL(url)
      document.body.removeChild(link)
      return response
    })
}

export default {
  get: <T = any>(option: AxiosConfig) => {
    return request({ method: 'get', ...option }) as Promise<IResponse<T>>
  },
  post: <T = any>(option: AxiosConfig) => {
    return request({ method: 'post', ...option }) as Promise<IResponse<T>>
  },
  delete: <T = any>(option: AxiosConfig) => {
    return request({ method: 'delete', ...option }) as Promise<IResponse<T>>
  },
  put: <T = any>(option: AxiosConfig) => {
    return request({ method: 'put', ...option }) as Promise<IResponse<T>>
  },
  cancelRequest: (url: string | string[]) => {
    return service.cancelRequest(url)
  },
  cancelAllRequest: () => {
    return service.cancelAllRequest()
  },
  downloadGet: <T = any>(option: AxiosConfig) => {
    return downloadFileRequest({ method: 'get', ...option }) as Promise<IResponse<T>>
  }
}
